﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace CalcCalorie
{
    public partial class Form1 : Form
    {
        Dish day = new Dish("", null);

        FormTree frmTree = new FormTree();

        DateTime ActDate = DateTime.Today;
        FormCld frmCld = new FormCld();

        String dPathSave;

        Dish LastDishes;

        public Form1()
        {
            InitializeComponent();

            Gl.fPathDB = Application.StartupPath + "\\Catalog.db";
            dPathSave = Application.StartupPath + "\\Save";
            if (!Directory.Exists(dPathSave)) Directory.CreateDirectory(dPathSave);

            ESpace.DBItem.LoadRec = new ESpace.LoadRecDelegate(Gl.LoadRec);

            #region *** конвертиция старых файлов и замена новыми **************
            // база данных
            if (File.Exists(Application.StartupPath + "\\DishList.dsh"))
            {
                DishOLD oldDb = new DishOLD(Application.StartupPath + "\\DishList.dsh", "");
                DIR DB = Gl.ConvertOldDb(oldDb);
                Gl.SaveDB(DB, Gl.fPathDB);

                //File.Delete(Application.StartupPath + "\\DishList.dsh"); // пока не надо, чтобы можно было вернуть
                File.Move(Application.StartupPath + "\\DishList.dsh", Application.StartupPath + "\\DishList.dshOld");
            }
            // файлы по дням
            string[] fl = Directory.GetFiles(dPathSave, "*.dshl");
            for (int i = 0; i < fl.Length; i++)
            {
                FileInfo fi = new FileInfo(fl[i]);
                string nm = fi.Name.Replace(".dshl", "");
                DishOLD oldDish = new DishOLD(fl[i], "");
                Dish dsh = Gl.ConvertOldDish(oldDish, null);
                Gl.SaveDish(dsh, dPathSave + "\\" + nm + ".DayNote");
                File.Delete(fl[i]);
            }
            #endregion *** конвертиция старых файлов и замена новыми **************

            LoadList(ActDate);
            LoadLastDishs();
            FillRacLb();
            tBtnData.Text = ActDate.ToString("dd.MM.yyyy");

            Gl.DB = Gl.LoadDB(Gl.fPathDB);
        }

        //*********************************************************************
        #region *** заполнение листов *************************
        
        void FillRacLb()
        {
            lbRec.Clear();
            for (int i = 0; i < day.Items.Count; i++)
            {
                lbRec.Add(day.Items[i].Name);
            }
            FillListLb(false);
        }

        void FillListLb(bool bSaveSelect)
        {
            int LastInd = lbList.SelectedIndex;
            lbList.Clear();

            int ind = lbRec.SelectedIndex;
            if (ind == -1)
            {
                FillInfo();
                return;
            }

            for (int i = 0; i < day.dl[ind].dl.Count; i++)
            {
                lbList.Add(day.dl[ind].dl[i].Name + " >> " + day.dl[ind].dl[i].Mass.ToString() + "гр");
            }

            if (bSaveSelect && LastInd < day.dl[ind].dl.Count)
                lbList.SelectedIndex = LastInd;

            FillInfo();
        }

        /// <summary>Заполнение информации за сутки, прием пищи и одного блюда</summary>
        void FillInfo()
        {
            if (day.dl.Count > 0)
            {
                lblDay.Text = day.ToString(2);
                lblMassDay.Text = day.GetTotalMass(2).ToString();
            }
            else
            {
                lblDay.Text = "";
                lblMassDay.Text = "";
            }

            int indR = lbRec.SelectedIndex;
            int indD = lbList.SelectedIndex;

            if (indR != -1)
            {
                lblRec.Text = day.dl[indR].ToString(1);
                lblMassRec.Text = day.dl[indR].GetTotalMass(1).ToString();
            }
            else
            {
                lblRec.Text = "";
                lblMassRec.Text = "";
            }

            if (indD != -1)
            {
                lblDish.Text = day.dl[indR].dl[indD].ToString();
                lblMassDish.Text = day.dl[indR].dl[indD].Mass.ToString();
            }
            else
            {
                lblDish.Text = "";
                lblMassDish.Text = "";
            }

        }

        #endregion *** заполнение листов *************************
        //*********************************************************************
        #region *** события LB *************************
       
        private void lbRec_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            int ind = lbRec.SelectedIndex;
            if (ind == -1) return;
            mBtnEdit_Click(null, null);
        }

        private void lbList_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            int ind = lbList.SelectedIndex;
            if (ind == -1) return;
            mBtnEditRecDish_Click(null, null);
        }

        private void lbRec_SelectedItemChanged(object Sender)
        {
            btnAddDish.Enabled = lbRec.SelectedIndex!=-1;
            FillListLb(false);
        }

        private void lbList_SelectedItemChanged(object Sender)
        {
            FillInfo();
        }

        #endregion *** события LB *************************
        //*********************************************************************
        #region *** события кнопок *************************

        // добавить прием пищи
        private void tBtnAddRec_Click(object sender, EventArgs e)
        {
            FormEditValue frmEd = new FormEditValue();

            string StartValue = "Завтрак";
            if (day.dl.Count > 0)
            { 
                switch(day.dl[day.dl.Count-1].Name.ToUpper())
                {
                    case "ЗАВТРАК": StartValue = "Обед"; break;
                    case "ОБЕД": StartValue = "Полдник"; break;
                    case "ПОЛДНИК": StartValue = "Ужин"; break;
                    case "УЖИН": StartValue = "Ужин1"; break;
                    case "УЖИН1": StartValue = "Ужин2"; break;
                    default: StartValue = ""; break;
                }
            }

            if (frmEd.ShowDialog("Прием пищи", StartValue, true, new FormEditValue.CheckRetValDelegate(CheckNameRec))) 
            {
                day.Items.Add(new Dish(frmEd.RetVal, day));
                FillRacLb();
                SaveList(ActDate);

                lbRec.SelectedIndex = day.dl.Count - 1;
            }
            frmEd.Dispose();
        }

        // добавление блюда
        private void tBtnAddDish_Click(object sender, EventArgs e)
        {
            FormAddDish frmAdd = new FormAddDish();
            int indR = lbRec.SelectedIndex;
            if (indR == -1) return;
            if (frmAdd.ShowDialog(true))
            {
                day.dl[indR].dl.Add(frmAdd.ReturnDish.Clone());
                day.dl[indR].dl[day.dl[indR].dl.Count - 1].Mass = frmAdd.mass;
                FillListLb(false);
                SaveList(ActDate);
                lbList.SelectedIndex = day.dl[indR].dl.Count - 1;

                AddLastDish(frmAdd.ReturnDish);
            }
            frmAdd.Dispose();
        }

        // общий список блюд
        private void tBrnShowDishList_Click(object sender, EventArgs e)
        {
            FormAddDish frmAdd = new FormAddDish();
            frmAdd.ShowDialog(false);
            frmAdd.Dispose();
        }

        private void tBtnShowTree_Click(object sender, EventArgs e)
        {
            day.FillTree(frmTree.treeView1);
            frmTree.ShowDialog();
        }

        private void tBtnData_Click(object sender, EventArgs e)
        {
            if (frmCld.ShowDialog(ActDate, Cursor.Position.Y, Left))
            {
                if (ActDate.Date == frmCld.SelectedDate.Date) return;
                ActDate = frmCld.SelectedDate;
                LoadList(ActDate);
                FillRacLb();
                tBtnData.Text = ActDate.ToString("dd.MM.yyyy");
            }
        }

        #endregion *** события кнопок *************************
        //*********************************************************************
        #region *** события меню *************************

        // редактировать блюдо записи
        private void mBtnEditRecDish_Click(object sender, EventArgs e)
        {
            FormEditValue frmEd = new FormEditValue();

            Dish actDish = day.dl[lbRec.SelectedIndex].dl[lbList.SelectedIndex];
            if (frmEd.ShowDialog("Масса блюда", actDish.Mass.ToString(), true, new FormEditValue.CheckRetValDelegate(Gl.CheckMass))) 
            { 
                actDish.Mass = Convert.ToInt32(frmEd.RetVal.Trim());
                FillListLb(true);
                SaveList(ActDate);
            }

            frmEd.Dispose();
        }

        string CheckNameRec(string val)
        {
            if (val.Trim() == "") return "Название приема пищи не может быть пустым";
            return "";
        }

        // редактирование названия приема пищи
        private void mBtnEdit_Click(object sender, EventArgs e)
        {
            FormEditValue frmEd = new FormEditValue();

            if (frmEd.ShowDialog("Прием пищи", day.dl[lbRec.SelectedIndex].Name, true, new FormEditValue.CheckRetValDelegate(CheckNameRec)))
            {
                day.dl[lbRec.SelectedIndex].Name = frmEd.RetVal.Trim();
                lbRec.Itm[lbRec.SelectedIndex].Str = "";
                lbRec.Itm[lbRec.SelectedIndex].Str = frmEd.RetVal.Trim();
                FillRacLb();
                SaveList(ActDate);
            }

            frmEd.Dispose();
        }

        private void menuRecDish_Opening(object sender, CancelEventArgs e)
        {
            if (lbRec.SelectedIndex == -1) { e.Cancel = true; return; }
            mBtnEditRecDish.Enabled = lbList.SelectedIndex != -1;
            mBtnDelRecDish.Enabled = lbList.SelectedIndex != -1;

            #region *** Последние блюда ***

            mSep1.Visible = LastDishes.dl.Count > 0; 
            while (menuRecDish.Items[0].Name != "mSep1") menuRecDish.Items.RemoveAt(0);
            
            ToolStripMenuItem itmMore = new ToolStripMenuItem("Еще", imList.Images[0]);

            for (int i = 0; i < LastDishes.dl.Count;i++ )
            {
                ToolStripMenuItem itm = new ToolStripMenuItem(LastDishes.dl[i].Name, imList.Images[1]);
                itm.Tag = LastDishes.dl[i];
                itm.Click += new EventHandler(mBtnLastDish_Click);

                if (i < Gl.LastDishesShowLen)
                {
                    menuRecDish.Items.Insert(i, itm);
                }
                else
                {
                    itmMore.DropDownItems.Insert(i - Gl.LastDishesShowLen, itm);
                }
            }
            if (LastDishes.dl.Count >= Gl.LastDishesShowLen) menuRecDish.Items.Insert(Gl.LastDishesShowLen, itmMore);

            #endregion *** Последние блюда ***
        }

        /// <summary> Событие выбора из списка последних блюд </summary>
        void mBtnLastDish_Click(object sender, EventArgs e)
        {
            FormEditValue frmEd = new FormEditValue();
            int indR = lbRec.SelectedIndex;
            Dish DishForAdd = (Dish)((ToolStripMenuItem)sender).Tag;
            if (frmEd.ShowDialog("Масса блюда", "", false, new FormEditValue.CheckRetValDelegate(Gl.CheckMass)))
            {
                day.dl[indR].dl.Add(DishForAdd.Clone());
                day.dl[indR].dl[day.dl[indR].dl.Count - 1].Mass = Convert.ToInt32(frmEd.RetVal.Trim());
                FillListLb(false);
                SaveList(ActDate);
                lbList.SelectedIndex = day.dl[indR].dl.Count - 1;

                AddLastDish(DishForAdd);
            }

            frmEd.Dispose();
        }

        private void MenuRec_Opening(object sender, CancelEventArgs e)
        {
            mBtnEdit.Enabled = lbRec.SelectedIndex != -1;
            mBtnDel.Enabled = lbRec.SelectedIndex != -1;
        }

        private void mBtnDel_Click(object sender, EventArgs e)
        {
            int ind = lbRec.SelectedIndex;

            if (MessageBox.Show("Действительно удалить?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                day.dl.RemoveAt(ind);
                SaveList(ActDate);
                FillRacLb();
            }
        }

        private void mBtnDelRecDish_Click(object sender, EventArgs e)
        {
            int ind = lbRec.SelectedIndex;
            int ind1 = lbList.SelectedIndex;
            if (MessageBox.Show("Действительно удалить?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
            {
                day.dl[ind].dl.RemoveAt(ind1);
                SaveList(ActDate);
                FillListLb(false);
            }
        }

        private void mBtnAddRec_Click(object sender, EventArgs e)
        {
            tBtnAddRec_Click(null, null);
        }

        private void mBtnAddRecDish_Click(object sender, EventArgs e)
        {
            tBtnAddDish_Click(null, null);
        }
        
        #endregion *** события меню *************************
        //*********************************************************************
        #region *** Load/Save *************************

        void LoadList(DateTime dt)
        {
            day = Gl.LoadDish(dPathSave + "\\" + dt.ToString("yyyy_MM_dd") + ".DayNote");
        }

        void SaveList(DateTime dt)
        {
            String fPath = dPathSave + "\\" + dt.ToString("yyyy_MM_dd") + ".DayNote";
            Gl.SaveDish(day, fPath);
        }

        void LoadLastDishs()
        {
            LastDishes = Gl.LoadDish(Application.StartupPath + "\\LastDishes.db");
        }

        void SaveLastDishs()
        {
            Gl.SaveDish(LastDishes, Application.StartupPath + "\\LastDishes.db");
        }

        #endregion *** Load/Save *************************
        
        //*********************************************************************
        /*private void btnConvertSave_Click(object sender, EventArgs e)
        {
            String[] fl = Directory.GetFiles(Application.StartupPath + "\\Save", "*.csv");
            for (int i = 0; i < fl.Length; i++)
            {
                ESpace.EFile f = new ESpace.EFile(fl[i]);
                Dish d = LoadList(fl[i]);
                // конвертируем для 100 гр
                for (int j = 0; j < d.dl.Count; j++)
                {
                    for (int g = 0; g < d.dl[j].dl.Count; g++)
                    {
                        d.dl[j].dl[g].B100 = d.dl[j].dl[g].B100 * 100.0 / (double)d.dl[j].dl[g].Mass;
                        d.dl[j].dl[g].G100 = d.dl[j].dl[g].G100 * 100.0 / (double)d.dl[j].dl[g].Mass;
                        d.dl[j].dl[g].U100 = d.dl[j].dl[g].U100 * 100.0 / (double)d.dl[j].dl[g].Mass;
                        d.dl[j].dl[g].Cc100 = d.dl[j].dl[g].Cc100 * 100.0 / (double)d.dl[j].dl[g].Mass;
                    }
                }

                //Gl.SaveDishTypeList(d, f.dPath + "\\" + f.Name.Substring(0, f.Name.Length - 1) + ".dshl");
                d.Save(f.dPath + "\\" + f.Name.Substring(0, f.Name.Length - 1) + ".dshl");
            }
        }*/

        private void lbRec_MoveItem(object Sender, int oldInd, int newInd)
        {
            Dish d = day.dl[oldInd];
            day.dl.RemoveAt(oldInd);
            day.dl.Insert(newInd, d);
            SaveList(ActDate);
        }

        private void lbList_MoveItem(object Sender, int oldInd, int newInd)
        {
            Dish d = day.dl[lbRec.SelectedIndex].dl[oldInd];
            day.dl[lbRec.SelectedIndex].dl.RemoveAt(oldInd);
            day.dl[lbRec.SelectedIndex].dl.Insert(newInd, d);
            SaveList(ActDate);
        }

        void AddLastDish(Dish dsh)
        { 
            int ind = LastDishes.IndexOfRecord(dsh.NameExt);
            if (ind != -1) LastDishes.dl.RemoveAt(ind);
            LastDishes.dl.Insert(0,dsh.Clone());
            while (LastDishes.dl.Count > Gl.LastDishesLen) LastDishes.dl.RemoveAt(LastDishes.dl.Count - 1);
            SaveLastDishs();
        }

    }
}
